package cn.shop.admin.service.impl;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.SaSessionCustomUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.shop.admin.common.util.CurrentUserUtil;
import cn.shop.admin.entity.backPermissionModule.BackPermission;
import cn.shop.admin.entity.backRoleModule.BackRole;
import cn.shop.admin.mapper.BackPermissionMapper;
import cn.shop.admin.mapper.BackRoleMapper;
import cn.shop.admin.mapper.BackUserMapper;
import cn.shop.admin.req.AssignPermissionReq;
import cn.shop.admin.service.BackPermissionService;
import cn.shop.base.MyServiceImpl;
import cn.shop.utils.exception.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 总后台 权限表(BackPermission)表服务实现类
 *
 * @author jzw
 * @since 2021-11-08 13:01:51
 */
@Service("backPermissionService")
public class BackPermissionServiceImpl extends MyServiceImpl<BackPermissionMapper, BackPermission> implements BackPermissionService {

	@Resource
	private BackUserMapper backUserMapper;

	@Resource
	private BackRoleMapper backRoleMapper;

	/**
	 * 新增数据
	 *
	 * @param permission 实体对象
	 * @return 新增结果
	 * @author jy
	 * @since 2022-01-17 15:47:07
	 */
	@Override
	public Boolean insert(BackPermission permission) {
		LambdaQueryWrapper<BackPermission> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(BackPermission::getCode, permission.getCode());
		BackPermission exist = baseMapper.selectOne(queryWrapper);
		if (exist != null) {
			throw new ServiceException("当前权限code已存在!");
		}
		permission.setEnable(true);
		permission.setInitial(false);
		return SqlHelper.retBool(baseMapper.insert(permission));
	}

	/**
	 * 修改数据
	 *
	 * @param permission 实体对象
	 * @return 修改结果
	 * @author jy
	 * @since 2022-01-17 15:47:07
	 */
	@Override
	public boolean update(BackPermission permission) {
		if (StrUtil.isNotBlank(permission.getCode())) {
			LambdaQueryWrapper<BackPermission> queryWrapper = Wrappers.lambdaQuery();
			queryWrapper.eq(BackPermission::getCode, permission.getCode()).ne(BackPermission::getId, permission.getId());
			BackPermission exist = baseMapper.selectOne(queryWrapper);
			if (exist != null) {
				throw new ServiceException("当前权限code已存在!");
			}
		}
		return SqlHelper.retBool(baseMapper.updateById(permission));
	}

	/**
	 * 分配权限
	 *
	 * @param assignPermissionReq 实体对象
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean assignPermissions(AssignPermissionReq assignPermissionReq) {
		List<Long> checkList = assignPermissionReq.getCheckList();
		List<Long> halfList = assignPermissionReq.getHalfList();
		Long id = assignPermissionReq.getRoleId();
		//将半选和全选封装到一起
		List<Map<String, Object>> dataList = new LinkedList<>();
		checkList.forEach(ele -> {
			Map<String, Object> dataMap = new HashMap<>(3);
			dataMap.put("permissionId", ele);
			dataMap.put("roleId", id);
			dataMap.put("checked", true);
			dataList.add(dataMap);
		});
		halfList.forEach(ele -> {
			Map<String, Object> dataMap = new HashMap<>(3);
			dataMap.put("permissionId", ele);
			dataMap.put("roleId", id);
			dataMap.put("checked", false);//表示半选
			dataList.add(dataMap);
		});
		if (dataList.isEmpty()) {
			return false;
		}
		baseMapper.removePermissionByRoleId(id);
		boolean res = SqlHelper.retBool(baseMapper.assignPermission(dataList));
		if (res) {
			// 去除角色的已有权限
			LambdaQueryWrapper<BackRole> query = Wrappers.lambdaQuery();
			query.eq(BackRole::getId, id);
			BackRole backRole = backRoleMapper.selectOne(query);
			SaSession session = SaSessionCustomUtil.getSessionById("role-" + backRole.getCode(), false);
			if (null != session) {
				session.delete("Permission_List");
			}
		}
		return res;
	}

	/**
	 * 查询完整权限树
	 *
	 * @author jzw
	 * @since 2021/11/8 14:02
	 */
	@Override
	public List<BackPermission> allPermissionTree() {
		LambdaQueryWrapper<BackPermission> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(BackPermission::getEnable, true).orderByAsc(BackPermission::getSort);
		List<BackPermission> permissions = baseMapper.selectList(queryWrapper);
		Map<Long, List<BackPermission>> collect = permissions.stream().collect(Collectors.groupingBy(BackPermission::getParentId));

		List<BackPermission> parent = collect.get(0L);
		parseList(parent, collect);
		return parent;
	}

	/**
	 * 递归拼接菜单
	 */
	private void parseList(List<BackPermission> parent, Map<Long, List<BackPermission>> permissions) {
		for (BackPermission permission : parent) {
			Long id = permission.getId();
			List<BackPermission> children = permissions.get(id);
			if (CollectionUtil.isNotEmpty(children)) {
				permission.setPChild(children);
				parseList(children, permissions);
			}
		}
	}

	/**
	 * 查询用户的权限树
	 *
	 * @param userId 用户id
	 * @author jzw
	 * @since 2021/11/8 14:02
	 */
	@Override
	public List<BackPermission> allPermissionTreeByUserId(Long userId) {
		List<BackPermission> backPermissions = baseMapper.allPermissionByUserId(userId);
		Map<Long, List<BackPermission>> collect = backPermissions.stream().collect(Collectors.groupingBy(BackPermission::getParentId));
		List<BackPermission> parent = collect.get(0L);
		for (BackPermission backPermission : parent) {
			Long id = backPermission.getId();
			List<BackPermission> children = collect.get(id);
			if (CollectionUtil.isNotEmpty(children)) {
				backPermission.setPChild(children);
			}
		}
		return parent;
	}

	/**
	 * 获取当前登录用户的权限url
	 *
	 * @return java.util.List<java.lang.String>
	 */
	@Override
	public List<String> getAllPermissionUrlByUserId() {
		return baseMapper.getAllPermissionUrlByUserId(CurrentUserUtil.getUserId());
	}

	/**
	 * 获取当前登录人的按钮权限信息
	 *
	 * @return java.util.List<java.lang.String>
	 * @author jy
	 * @since 2020/8/24 21:51
	 */
	@Override
	public List<String> getAllBtnPermissionByUserId() {
		return baseMapper.getAllBtnPermissionByUserId(CurrentUserUtil.getUserId());
	}

}

